package com.bruce.asurada.sso.client.controller;

import com.bruce.asurada.sso.client.common.Result;
import com.bruce.asurada.sso.client.dto.LoginResponseDto;
import com.bruce.asurada.sso.client.dto.UserInfoDto;
import com.bruce.asurada.sso.client.dto.UserLoginDto;
import com.bruce.asurada.sso.client.service.SsoClientService;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

/**
 * SSO控制器 - 统一处理UI展示和API接口
 */
@Controller
@RequestMapping("/")
public class SsoController {

    private static final Logger logger = LoggerFactory.getLogger(SsoController.class);
    private static final String TOKEN_COOKIE_NAME = "sso_token";

    @Autowired
    private SsoClientService ssoClientService;

    // ==================== UI页面路由 ====================

    /**
     * 首页
     */
    @GetMapping
    public String home(HttpServletRequest request, Model model) {
        // 检查是否已登录
        UserInfoDto userInfo = (UserInfoDto) request.getAttribute("currentUser");
        boolean isLoggedIn = userInfo != null;
        
        model.addAttribute("isLoggedIn", isLoggedIn);
        model.addAttribute("user", userInfo);
        model.addAttribute("title", "首页");
        
        return "home";
    }

    /**
     * 登录页面
     */
    @GetMapping("/login")
    public String loginPage(Model model) {
        model.addAttribute("title", "用户登录");
        return "login";
    }

    /**
     * 受保护页面
     */
    @GetMapping("/protected")
    public String protectedPage(HttpServletRequest request, Model model) {
        UserInfoDto userInfo = (UserInfoDto) request.getAttribute("currentUser");
        model.addAttribute("user", userInfo);
        model.addAttribute("title", "受保护页面");
        return "protected";
    }

    /**
     * 用户信息页面
     */
    @GetMapping("/profile")
    public String profilePage(HttpServletRequest request, Model model) {
        UserInfoDto userInfo = (UserInfoDto) request.getAttribute("currentUser");
        model.addAttribute("user", userInfo);
        model.addAttribute("title", "用户信息");
        return "profile";
    }

    // ==================== API接口 ====================

    /**
     * 登录接口
     */
    @PostMapping("/api/login")
    @ResponseBody
    public Result<LoginResponseDto> login(@RequestBody UserLoginDto loginDto, HttpServletResponse response) {
        logger.info("用户登录请求: {}", loginDto.getAccount());
        
        try {
            Result<LoginResponseDto> result = ssoClientService.login(loginDto, "web");
            
            if (result.isSuccess() && result.getData() != null) {
                // 设置令牌Cookie
                String token = result.getData().getAccessToken();
                Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, token);
                cookie.setHttpOnly(true);
                cookie.setPath("/");
                cookie.setMaxAge(7 * 24 * 60 * 60); // 7天
                response.addCookie(cookie);
                
                logger.info("用户登录成功: {}", loginDto.getAccount());
            } else {
                logger.warn("用户登录失败: {}, 原因: {}", loginDto.getAccount(), result.getMessage());
            }
            
            return result;
        } catch (Exception e) {
            logger.error("登录过程中发生异常: {}", e.getMessage(), e);
            return Result.error("登录失败，请稍后重试");
        }
    }

    /**
     * 登出接口
     */
    @PostMapping("/api/logout")
    @ResponseBody
    public Result<Void> logout(HttpServletRequest request, HttpServletResponse response) {
        try {
            String token = extractTokenFromRequest(request);
            if (token != null) {
                ssoClientService.logout(token, null);
            }
            
            // 清除令牌Cookie
            Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, "");
            cookie.setHttpOnly(true);
            cookie.setPath("/");
            cookie.setMaxAge(0);
            response.addCookie(cookie);
            
            logger.info("用户登出成功");
            return Result.success();
        } catch (Exception e) {
            logger.error("登出过程中发生异常: {}", e.getMessage(), e);
            return Result.error("登出失败");
        }
    }

    /**
     * 刷新令牌接口
     */
    @PostMapping("/api/refresh")
    @ResponseBody
    public Result<LoginResponseDto> refreshToken(HttpServletRequest request, HttpServletResponse response) {
        try {
            String token = extractTokenFromRequest(request);
            if (token == null) {
                return Result.error("未找到令牌");
            }
            
            Result<LoginResponseDto> result = ssoClientService.refreshToken(token);
            
            if (result.isSuccess() && result.getData() != null) {
                // 更新令牌Cookie
                String newToken = result.getData().getAccessToken();
                Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, newToken);
                cookie.setHttpOnly(true);
                cookie.setPath("/");
                cookie.setMaxAge(7 * 24 * 60 * 60); // 7天
                response.addCookie(cookie);
                
                logger.info("令牌刷新成功");
            }
            
            return result;
        } catch (Exception e) {
            logger.error("刷新令牌过程中发生异常: {}", e.getMessage(), e);
            return Result.error("刷新令牌失败");
        }
    }

    /**
     * 获取用户信息接口
     */
    @GetMapping("/api/user")
    @ResponseBody
    public Result<UserInfoDto> getUserInfo(HttpServletRequest request) {
        try {
            String token = extractTokenFromRequest(request);
            if (token == null) {
                return Result.error("未找到令牌");
            }
            
            return ssoClientService.getUserInfo(token);
        } catch (Exception e) {
            logger.error("获取用户信息过程中发生异常: {}", e.getMessage(), e);
            return Result.error("获取用户信息失败");
        }
    }

    /**
     * 验证令牌接口
     */
    @GetMapping("/api/verify")
    @ResponseBody
    public Result<UserInfoDto> verifyToken(HttpServletRequest request) {
        try {
            String token = extractTokenFromRequest(request);
            if (token == null) {
                return Result.error("未找到令牌");
            }
            
            return ssoClientService.verifyToken(token);
        } catch (Exception e) {
            logger.error("验证令牌过程中发生异常: {}", e.getMessage(), e);
            return Result.error("验证令牌失败");
        }
    }

    /**
     * 检查登录状态接口
     */
    @GetMapping("/api/status")
    @ResponseBody
    public Result<Boolean> checkLoginStatus(HttpServletRequest request) {
        try {
            String token = extractTokenFromRequest(request);
            if (token == null) {
                return Result.success(false);
            }
            
            Result<UserInfoDto> result = ssoClientService.verifyToken(token);
            return Result.success(result.isSuccess());
        } catch (Exception e) {
            logger.error("检查登录状态过程中发生异常: {}", e.getMessage(), e);
            return Result.success(false);
        }
    }

    /**
     * SSO回调处理
     */
    @GetMapping("/callback")
    public String callback(@RequestParam(required = false) String token, 
                          @RequestParam(required = false) String error,
                          HttpServletResponse response) {
        if (error != null) {
            logger.warn("SSO回调返回错误: {}", error);
            return "redirect:/login?error=" + error;
        }
        
        if (token != null) {
            // 设置令牌Cookie
            Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, token);
            cookie.setHttpOnly(true);
            cookie.setPath("/");
            cookie.setMaxAge(7 * 24 * 60 * 60); // 7天
            response.addCookie(cookie);
            
            logger.info("SSO回调成功，令牌已设置");
            return "redirect:/";
        }
        
        logger.warn("SSO回调缺少必要参数");
        return "redirect:/login?error=invalid_callback";
    }

    // ==================== 私有方法 ====================

    /**
     * 从请求中提取令牌
     */
    private String extractTokenFromRequest(HttpServletRequest request) {
        // 优先从Cookie中获取
        if (request.getCookies() != null) {
            for (Cookie cookie : request.getCookies()) {
                if (TOKEN_COOKIE_NAME.equals(cookie.getName())) {
                    return cookie.getValue();
                }
            }
        }
        
        // 从Authorization头获取
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        
        // 从请求参数获取
        return request.getParameter("token");
    }
}